-- UIBossEffect
-- Create by chendh
-- Boss特效界面

-- UIBossEffect继承自Layer
UIBossEffect = class("UIBossEffect", function()
    return cc.Layer:create();
end);

local instance = nil;

function UIBossEffect.getInstance()
    if instance == nil then
        instance = UIBossEffect.new();
    end

    return instance;
end

function UIBossEffect.create(actionType, para)
    return UIBossEffect.new(actionType, para);
end

function UIBossEffect:ctor(actionType, para)
    -- 初始化
    self:setName("UIBossEffect");
    self:setLocalZOrder(UIMgr.TOP_MENU_ZORDER + 1);

    local node = cc.CSLoader:createNode("layout/dungeon/BossEffect.csb");
    self:addChild(node);
    self.node = node;
    local CT = node:getChildByName("CT");

    -- 注册事件处理回调函数
    self:registerEventCallback();

    self.CT = CT;
    self.actionType = actionType;
    self.pos = para.pos;
    self.skillId = para.skillId;
    self.callBack = para.callBack;

    -- 适配
    self:resize(node);

    -- 初始化
    self:initView();

    self:gotoSelectState();

    -- 注册点击事件
    self:registerTouchEvent(node);
end

-- 初始化动作参数
function UIBossEffect:initPara(display)
    local monsterDisplay = MonsterDisplayM.getMonsterSkillDisplay(self.classId, self.skillId);
    local para = monsterDisplay.para;
    if type(para) ~= "table" then return; end

    -- 注册帧震动
    local shake = para["frame_shake"];
    if shake then
        display:registerFrameEvent(shake["frame"], function()
            local form = UIMgr:getCurrentScene():getFormByName("UIDungeonMain");
            if form then playShakeEffect(form.node, 0.03, 6, shake["times"]); end
            playShakeEffect(self, 0.03, 6, shake["times"]);
        end);
    end

    -- 帧回调
    local frame = para["frame_callback"];
    if frame and self.callBack then
        display:registerFrameEvent(frame, function()
            self:callBack();
        end);
    end
end

-- 初始化模型
function UIBossEffect:initView()
    -- 创建英雄模型
    self:createHeroModel();

    -- 创建BOSS模型
    self:createBossModel();

    -- 播放BOSS特效
    self:playBossActionAndEffect();

    -- 播放特效音效
    self:palyMusic();
end

-- 播放动画
function UIBossEffect:playBossActionAndEffect()
    local bgNode = findChildByName(self.node, "bg_mask/bgImg");
    local bgNode2 = findChildByName(self.node, "bg_mask2/bgImg");
    local panel = findChildByName(self.node, "CT/panel");
    local effectNode = findChildByName(self.node, "CT/effect_node");
    local pos = self.pos;
    local grid = findChildByName(panel, "grid" .. pos);
    local displayInfo = MonsterDisplayM.getMonsterSkillDisplay(self.classId, self.skillId);

    if not grid then
        -- 没有找到怪物节点，直接返回
        UIMgr.getCurrentScene():removeFormByName("UIBossEffect");
    end

    -- 是否需要背景
    local needMask = displayInfo.need_mask;
    if not needMask or needMask == "" then
        needMask = 1;
    end

    local time = iif(needMask == 1, 1.5, 0);

    -- 先是背景淡入
    local para = displayInfo.para or {};
    local fadeTime = para.fade_time or 1.5;
    local fadeOut = cc.FadeOut:create(fadeTime);
    local fadeIn = cc.FadeTo:create(fadeTime, 250);
    local delay = cc.DelayTime:create(displayInfo.lock_screen);

    local callFunc = cc.CallFunc:create(function()
        UIMgr.getCurrentScene():removeFormByName("UIBossEffect");
    end);

    bgNode:setOpacity(0);
    bgNode2:setOpacity(0);

    if needMask == 1 then
        bgNode:runAction(cc.Sequence:create(fadeIn, delay, fadeOut, callFunc));
        bgNode2:runAction(cc.Sequence:create(fadeIn, delay, fadeOut, callFunc));
    else
        bgNode:runAction(cc.Sequence:create(delay, callFunc));
        bgNode2:runAction(cc.Sequence:create(delay, callFunc));
    end

    -- 根据动作根据播放对应的动画效果
    local delayTime = 0;
    if self.actionType == MONSTER_ACTION_ACCOMPANY then
        -- 播放通用的交替伴生物的动画效果
        delayTime = self:playAccompanyEffect(effectNode, grid);
    else
        -- 播放模型自带的动画效果
        delayTime = self:playNormalActionEffect(effectNode, grid, displayInfo);
        delaytime = delayTime or 0;
    end

    -- BOSS动画播放结束处理
    performWithDelay(self, self.onEffectEnd, delayTime);
end

-- 播放音效
function UIBossEffect:palyMusic()
    local monsterDisplay = MonsterDisplayM.getMonsterSkillDisplay(self.classId, self.skillId);
    local audio = monsterDisplay.audio;
    local delayTime = monsterDisplay.delaytime;

    if type(delayTime) ~= "number" or not audio then
        return;
    end

    performWithDelay(self, function() AudioM.playFx(audio); end, delayTime);
end

-- 创建英雄模型
function UIBossEffect:createHeroModel()
    local headImg   = findChildByName(self.node, "CT2/head_icon");
    local modelNode = findChildByName(self.node, "CT2/model_node");

    -- 获取当前出战英雄
    local pet = ME.user:getActivePet();
    local classId = pet.classId;
    local petInfo = PetM.queryModel(pet:getModelId());

    local iconPath = getHeroIconPath(pet:getIcon());
    modelNode:removeAllChildren();
    self.heroModel = createHeroModel(pet:getModelId(), headImg, modelNode, petInfo["model_scale"], iconPath);
end

-- 创建Boss模型
function UIBossEffect:createBossModel()
    -- 获取所有格子
    local grids = UIDungeonMgr:getCurLevel():getAllGrids();
    local panel = findChildByName(self.node, "CT/panel");

    local w = AlignM.frameSize.width;
    local h = AlignM.frameSize.height;

    local scale;
    if h / w > 1.5 then
        scale = w / (DESIGN_WIDTH);
    else
        -- 在宽高比小于等于1.5时（如iphone或ipad），需要略微比预定比例缩小些。 所以加了75像素
        scale = h / (DESIGN_HEIGHT + 75);
    end

    -- 获取已开启的怪物格子, 重新生成怪物模型放在select_target_node上
    local openMonsterGrids = UIDungeonMgr:getCurLevel():getOpenMonsterGrids();
    for i = 1, #openMonsterGrids do
        local monsterGrid = openMonsterGrids[i];
        local worldPos = monsterGrid:convertToWorldSpace(cc.p(0, 0));

        local classId = monsterGrid.gridData.monster.classId;

        local monsterNode = cc.Node:create();

        if monsterGrid.gridData.monster and MonsterM.query(monsterGrid.gridData.monster.classId, "monster_type") == MONSTER_TYPE_BOSS then
            -- 报错保护SLIMEC-1715
            local classId = monsterGrid.gridData.monster.classId;
            local changeClassId = monsterGrid.gridData.monster.dbase:query("changeClassId");
            local lastClassId = monsterGrid.monsterNode.last_class_id;
            local lastAccompanyClassId = monsterGrid.monsterNode.last_accompany_class_id;

            if lastClassId and lastAccompanyClassId then
                classId = lastClassId;

                monsterGrid.monsterNode.last_class_id = nil;
                monsterGrid.monsterNode.last_accompany_class_id = nil;
            end

            -- 如果是释放技能的怪物，那么保存下class_id
            if monsterGrid.gridData:getPos() == self.pos then
                self.classId = classId;
                self.changeClassId = changeClassId;
            end

            if monsterGrid.gridData.type == GRID_TYPE_GHOST_SHIP and not changeClassId then
                -- 幽灵船
                createShipModel(monsterNode, classId);
            else
                -- 普通怪物
                local display;

                if changeClassId then
                    display = monsterGrid:createExtraMonsterDisplay(changeClassId);
                else
                    -- 根据配置，创建伴生物模型
                    local dbase = MonsterM.query(classId, "dbase");
                    local accompanyId = dbase["accompany_monster_id"];
                    if type(accompanyId) == "number" then
                        local accompanyDisplay = monsterGrid:createAccompanyDisplay(accompanyId);
                        monsterNode:addChild(accompanyDisplay);
                        monsterNode.accompanyDisplay = accompanyDisplay;
                    end                    

                    -- 创建怪物模型
                    display = monsterGrid:createMonsterDisplay(classId, {["skillId"] = self.skillId});

                    -- 偏移
                    local offsetX = 0;
                    local offsetY = 0;
                    local displayInfo = MonsterDisplayM.getMonsterSkillDisplay(self.classId, self.skillId);
                    if type(displayInfo) == "table" and 
                        type(displayInfo.offset_x) == "number" and 
                        type(displayInfo.offset_y) == "number" then
                        display:setPosition(
                            display:getPositionX() + displayInfo.offset_x, 
                            display:getPositionY() + displayInfo.offset_y
                        );
                    end

                    -- 暂停下动作，因为在模型创建后会自动播放待机动画
                    -- 而待机动画和特效动画衔接不上
                    --display.normalAnimation:pause();
                end

                monsterNode:addChild(display);
                monsterNode.monsterDisplay = display;

                -- 需要停止动作
                if monsterGrid:getIsPause() then
                    display:pauseActions();

                    if monsterNode.accompanyDisplay then
                        monsterNode.accompanyDisplay:pauseActions();
                    end
                end
            end

            monsterNode:setPositionY(12);

            local grid = cc.Node:create();
            grid:addChild(monsterNode);
            grid.monsterNode = monsterNode;
            grid.gridData = monsterGrid.gridData;
            grid.pos = monsterGrid.gridData:getPos();
            grid:setName("grid" .. grid.pos);

            local toPos = panel:convertToNodeSpace(worldPos);
            grid:setPosition(toPos);
            grid:setScale(DUNGEON_AJUST_SCALE);

            if MonsterM.query(classId, "monster_type") == MONSTER_TYPE_BOSS then
                -- 设置boss格子的层级，防止被其他格子覆盖
                grid:setLocalZOrder(10000);
            end

            if not openMonsterGrids[i].gridData.monster:isDead() then
                -- 有可能怪物已经死亡
                panel:addChild(grid);
            end
        end
    end

end

-- 注册点击事件
function UIBossEffect:registerTouchEvent(node)
    --[[local bgNode = findChildByName(node, "bg_mask/bgImg");
    bgNode:setTouchEnabled(true);

    local function onBgClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_return");
            -- 点击关闭
            UIMgr.getCurrentScene():removeFormByName("UIBossEffect");
        end
    end

    AddBackEventHandler(self, bgNode, onBgClick);]]
end

-- 注册事件处理回调函数
function UIBossEffect:registerEventCallback()
    -- 注册获得焦点的回调
    EventMgr.register("UIBossEffect", event.FOCUS_CHANGED, function(para)
        if "UIBossEffect" == para["get"] then
            self.hideFormList = {};

            local curFormList = UIMgr.getCurrentScene().forms;
            for num = #curFormList - 1, 1, -1 do
                local form = curFormList[num];
                if form:getName() == "UIDungeonMain" then
                    break;
                else
                    form:setVisible(false);
                    table.insert(self.hideFormList, form:getName());
                end
            end
        end
    end);

    -- 界面析构后，需要清理下
    self:registerScriptHandler(function(ev)
        if ev == "exit" then
            self:clearSelectState();
            EventMgr.removeAll("UIBossEffect");

            if not UIDungeonMgr:getCurLevel() then
                return;
            end
            UIDungeonMgr:getCurLevel():showHeroModex();

            self.hideFormList = self.hideFormList or {};

            for _, formName in ipairs(self.hideFormList) do
                local form = UIMgr.getCurrentScene():getFormByName(formName);
                if form then
                    form:setVisible(true);
                end
            end
            self.hideFormList = {};

        elseif ev == "enter" then
            if not UIDungeonMgr:getCurLevel() then
                return;
            end
            UIDungeonMgr:getCurLevel():hideHeroModex();
        end
    end);
end

-- 适配
function UIBossEffect:resize(node)
    local w = AlignM.frameSize.width;
    local h = AlignM.frameSize.height;

    local scale;
    if h / w > 1.5 then
        scale = w / (DESIGN_WIDTH);
    else
        -- 在宽高比小于等于1.5时（如iphone或ipad），需要略微比预定比例缩小些。 所以加了75像素
        scale = h / (DESIGN_HEIGHT + 75);
    end

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg_mask");

    -- 拉伸充满整个屏幕
    local bg = node:getChildByName("bg_mask");
    local bgImg = bg:getChildByName("bgImg");

    bg:setContentSize(w, h);
    bgImg:setContentSize(w + 20, h + 20);
    bg:setPosition(w / 2, h / 2);

    local bg = node:getChildByName("bg_mask2");
    local bgImg = bg:getChildByName("bgImg");

    bg:setContentSize(w, h);
    bgImg:setContentSize(w + 20, h + 20);
    bg:setPosition(w / 2, h / 2);

    -- CT 中心对齐， 并缩放到合适大小
    --AlignM.alignToCenter(node, "CT");

    -- 蒙版需要拉伸至正常大小
    local CT = findChildByName(node, "CT");
    local panel = findChildByName(CT, "panel");
    panel:setContentSize(w, h)
    panel:setPosition(0, 0)
    panel:setScale(scale);

    local scale2;
    if h / w >= 1.5 then
        scale2 = w / (DESIGN_WIDTH);
    else
        scale2 = h / (DESIGN_HEIGHT);
    end

    -- 底部菜单按原来适配规则缩放
    local ct2 = findChildByName(node, "CT2");
    ct2:setPosition(w / 2, 0);
    ct2:setScale(scale2);
end

-- 显示蒙版
function UIBossEffect:gotoSelectState()
    -- 获取所有格子，设置为技能目标选择状态
    local grids = UIDungeonMgr:getCurLevel():getAllGrids();
    --for i = 1, #grids do
        grids[18]:gotoSelectState(false, "bossEffect");
    --end
end

-- 隐藏蒙版
function UIBossEffect:clearSelectState()
    -- 获取所有格子，清除技能目标选择状态
    local grids = UIDungeonMgr:getCurLevel():getAllGrids();
    for i = 1, #grids do
        grids[i]:clearSelectState("bossEffect");
    end
end

-- BOSS动画播放结束处理
function UIBossEffect:onEffectEnd()
    local grids = UIDungeonMgr:getCurLevel():getAllGrids();
    local panel = findChildByName(self.node, "CT/panel");

    for i = 1, #grids do
        local monsterGrid = grids[i];
        if monsterGrid.isHide then
            monsterGrid.isHide = nil;

            -- 把UIDungeonMain隐藏的怪物显示出来
            local pos = monsterGrid.gridData:getPos();
            monsterGrid:onRefreshMonster(pos);
            UIDungeonMgr:getCurLevel():openGrid(pos, monsterGrid.type, true);
            monsterGrid:gotoSelectState(false, "bossEffect");

            -- 播放下怪物出场光效，并且在本界面也刷出一头怪物
            local worldPos = monsterGrid:convertToWorldSpace(cc.p(0, 0));

            local monsterNode = cc.Node:create();
            -- 报错保护SLIMEC-1715
            local classId = monsterGrid.gridData.monster.classId;

            -- 普通怪物
            local display = monsterGrid:createMonsterDisplay(classId);

            monsterNode:addChild(display);
            monsterNode.monsterDisplay = display;

            -- 需要停止动作
            if monsterGrid:getIsPause() then
                display:pauseActions();
            end

            monsterNode:setPositionY(12);

            local grid = cc.Node:create();
            grid:addChild(monsterNode);
            grid.monsterNode = monsterNode;
            grid.gridData = monsterGrid.gridData;
            grid.pos = pos;
            grid:setName("grid" .. pos);

            local toPos = panel:convertToNodeSpace(worldPos);
            grid:setPosition(toPos);
            grid:setScale(DUNGEON_AJUST_SCALE);

            if MonsterM.query(classId, "monster_type") == MONSTER_TYPE_BOSS then
                -- 设置boss格子的层级，防止被其他格子覆盖
                grid:setLocalZOrder(10000);
            end

            if not monsterGrid.gridData.monster:isDead() then
                -- 有可能怪物已经死亡
                panel:addChild(grid);
            end

            playEffect(grid, 1270, 0 ,50);
        end
    end
end

-- 播放模型自带的动画效果
function UIBossEffect:playNormalActionEffect(effectNode, grid, displayInfo)
    -- 播放聚气特效
    if displayInfo.energy_storage == 1 then
        performWithDelay(self, function ()
            local effectId = 1520;
            playEffect(grid, effectId, 0, 50);
        end, 0.3);
    end

    -- 慢动作
    local endSpeed = 2;
    local changeSpeed = 0.2;
    local startSpeed = 1;
    local function slowDown()
        -- 调整动作播放速度
        if nil == grid or nil == grid.monsterNode or nil == grid.monsterNode.monsterDisplay then
            return false;
        end

        local needSlowDown = displayInfo.slow_down;
        if not needSlowDown or needSlowDown == 0 then
            return true;
        end

        local speed = grid.monsterNode.monsterDisplay.initSpeed;

        if not speed then
            speed = grid.monsterNode.monsterDisplay:getSpeed();
            grid.monsterNode.monsterDisplay.initSpeed = speed;
        end
        grid.monsterNode.monsterDisplay:setSpeed(speed / startSpeed);

        startSpeed = startSpeed + changeSpeed;

        if startSpeed < endSpeed then
            performWithDelay(self, slowDown, 0.1);
        end

        return true;
    end

    if false == slowDown() then
        return 0;
    end

    -- 攻击延时
    local attackDeley = displayInfo.attack_delay;
    if not attackDeley or attackDeley == "" then
        attackDeley = 0.6;
    end

    local delayTime = displayInfo.start_time;
    performWithDelay(self, function ()
        -- 播放攻击动作
        local speed = displayInfo.attack_speed;
        local frame = displayInfo.attack_frame;
        grid.monsterNode.monsterDisplay:switchAction(self.actionType, {
            ["skillId"] = self.skillId,
            ["speed"] = speed,
            ["frame"] = frame,
        });

        grid.monsterNode.monsterDisplay:setSpeed(speed / 2);

        self:initPara(grid.monsterNode.monsterDisplay);

        performWithDelay(self, function()
            local speed = grid.monsterNode.monsterDisplay:getSpeed();
            grid.monsterNode.monsterDisplay:setSpeed(speed * 2);
        end, 1.2);

        -- 播放怪物攻击光效
        playMonsterAttackEffect(grid, self.classId, self.skillId, effectNode);
    end, delayTime + attackDeley);

    -- 屏幕震动
    local shakeInfo = type(displayInfo.shake) == "table" and displayInfo.shake or {0, 0};

    if type(shakeInfo) == "table" and #shakeInfo == 2 then
        performWithDelay(self, function ()
            playShakeEffect(self, 0.03, 8, shakeInfo[1] / 0.03 / 2);
        end, shakeInfo[2] + delayTime);
    end

    -- 持续播放受创效果
    local function playDamageAction(displayNode, delay)
        local modelId = displayNode.modelId;
        local damageFrame = PetM.queryModel(modelId, "damaged_frame");
        local speed = PetM.queryModel(modelId, "damaged_speed");

        -- 光效
        local para = displayInfo.para or {};
        if para["damage_effect"] then
            playEffect(displayNode, para["damage_effect"]);
        end

        -- 连续播放受创动作中的受创右偏部分
        displayNode.animation:play(MONSTER_ACTION_DAMAGED, true, damageFrame[1] + 3, damageFrame[2], speed);

        -- 切换成待机动作
        performWithDelay(self, function ()
            displayNode:switchAction(HERO_ACTION_IDLE);
        end, delay);
    end

    -- 播放受创动作
    local targetType = SkillM.query(self.skillId, "target");
    if targetType == DEFENSER and self.heroModel then
        if type(shakeInfo) == "table" and #shakeInfo == 2 then
            -- 如果有配置受创延迟时间，那么用配置的，否则用默认的
            local damageDelay = shakeInfo[2] + delayTime;

            local para = displayInfo.para;
            if type(para) == "table" and type(para["damage_delay"]) == "number" then
                damageDelay = para["damage_delay"];
            end

            performWithDelay(self, function ()
                local heroDisplay = findChildByName(self.heroModel, "HeroDisplay");
                -- 持续播放受创效果
                playDamageAction(heroDisplay, shakeInfo[1] + 0.5);
            end, damageDelay);
        end
    end

    return delayTime + shakeInfo[1] + shakeInfo[2];
end

-- 播放通用的交替伴生物的动画效果
function UIBossEffect:playAccompanyEffect(effectNode, grid, maxOffset, maxScaleOffset)
    -- 找到交替节点
    local monsterNode = grid.monsterNode;
    local mainNode = monsterNode.monsterDisplay;
    local secondaryNode = monsterNode.accompanyDisplay;

    -- 计算一些偏移量
    maxOffset = maxOffset or 200;
    local dif1;
    local dif2;

    -- 模型最大缩放值
    local maxScaleOffset = maxScaleOffset or 0.3;

    -- 原始的id
    local dungeonId = DungeonM.getDungeonId();
    local elementId = DungeonBossM.query(dungeonId, "boss_elem");
    local dbase = DungeonM.queryElement(elementId, "dbase");
    local originClassId = dbase["class_id"];

    local time1 = 0.3;
    local time2 = 1.5;

    local worldPos = mainNode:convertToWorldSpaceAR(cc.p(0, 0));
    local nodePos = effectNode:convertToNodeSpace(worldPos);

    -- 移动
    if originClassId == self.classId then
        dif1 = 120;
        dif2 = 80;

        -- 大的模型移动
        local moveLeft1 = cc.EaseOut:create(cc.MoveTo:create(time1, cc.p(mainNode:getPositionX() - maxOffset, mainNode:getPositionY())), time2);
        local scaleDown1 = cc.EaseOut:create(cc.ScaleTo:create(time1, mainNode:getScale() - maxScaleOffset/2), time2);
        local spawn1 = cc.Spawn:create(moveLeft1, scaleDown1);

        local callFunc1 = cc.CallFunc:create(function()
            -- 光效
            local _, node = playEffect(effectNode, 1335, nodePos.x + 10, nodePos.y + 160);

            performWithDelay(node, function() node:removeFromParent(); end, 1);
        end);

        local callFunc2 = cc.CallFunc:create(function()
            -- 修改层级
            mainNode:setLocalZOrder(secondaryNode:getLocalZOrder() - 1);
        end);

        local moveRight1 = cc.EaseIn:create(cc.MoveTo:create(time1, cc.p(mainNode:getPositionX() - 130, mainNode:getPositionY() - 10)), time2);
        local scaleDown2 = cc.EaseIn:create(cc.ScaleTo:create(time1, mainNode:getScale() - maxScaleOffset), time2);
        local spawn2 = cc.Spawn:create(moveRight1, scaleDown2);

        mainNode:runAction(cc.Sequence:create(callFunc1, spawn1, callFunc2, spawn2));

        -- 小的模型移动
        local moveRight2 = cc.EaseOut:create(cc.MoveTo:create(time1, cc.p(secondaryNode:getPositionX() + dif2, secondaryNode:getPositionY())), time2);
        local scaleUp1 = cc.EaseOut:create(cc.ScaleTo:create(time1, secondaryNode:getScale() + maxScaleOffset/2), time2);
        local spawn3 = cc.Spawn:create(moveRight2, scaleUp1);

        local moveLeft2 = cc.EaseIn:create(cc.MoveTo:create(time1, cc.p(secondaryNode:getPositionX() - dif1, secondaryNode:getPositionY())), time2);
        local scaleUp2 = cc.EaseIn:create(cc.ScaleTo:create(time1, secondaryNode:getScale() + maxScaleOffset), time2);
        local spawn4 = cc.Spawn:create(moveLeft2, scaleUp2);

        secondaryNode:runAction(cc.Sequence:create(spawn3, spawn4));

    else
        dif1 = 130;
        dif2 = 70;

        local offsetY = 10;

        -- 小的模型移动
        local moveLeft1 = cc.EaseOut:create(cc.MoveTo:create(time1, cc.p(secondaryNode:getPositionX() - dif2, secondaryNode:getPositionY() + offsetY)), time2);
        local scaleUp1 = cc.EaseOut:create(cc.ScaleTo:create(time1, secondaryNode:getScale() + maxScaleOffset/2), time2);
        local spawn1 = cc.Spawn:create(moveLeft1, scaleUp1);

        local callFunc1 = cc.CallFunc:create(function()
            -- 光效
            local _, node = playEffect(effectNode, 1335, nodePos.x - 50, nodePos.y + 180);

            performWithDelay(node, function() node:removeFromParent(); end, 1);
        end);

        local callFunc2 = cc.CallFunc:create(function()
            -- 修改层级
            secondaryNode:setLocalZOrder(mainNode:getLocalZOrder() + 1);
        end);

        local moveRight1 = cc.EaseIn:create(cc.MoveTo:create(time1, cc.p(secondaryNode:getPositionX() + dif1, secondaryNode:getPositionY() + offsetY)), time2);
        local scaleUp2 = cc.EaseIn:create(cc.ScaleTo:create(time1, secondaryNode:getScale() + maxScaleOffset), time2);
        local spawn2 = cc.Spawn:create(moveRight1, scaleUp2);

        secondaryNode:runAction(cc.Sequence:create(callFunc1, spawn1, callFunc2, spawn2));

        -- 大的模型移动
        local moveRight2 = cc.EaseOut:create(cc.MoveTo:create(time1, cc.p(mainNode:getPositionX() + maxOffset, mainNode:getPositionY() + offsetY)), time2);
        local scaleDown1 = cc.EaseOut:create(cc.ScaleTo:create(time1, mainNode:getScale() - maxScaleOffset/2), time2);
        local spawn3 = cc.Spawn:create(moveRight2, scaleDown1);

        local moveLeft2 = cc.EaseIn:create(cc.MoveTo:create(time1, cc.p(mainNode:getPositionX() + 120, mainNode:getPositionY())), time2);
        local scaleDown2 = cc.EaseIn:create(cc.ScaleTo:create(time1, mainNode:getScale() - maxScaleOffset), time2);
        local spawn4 = cc.Spawn:create(moveLeft2, scaleDown2);

        mainNode:runAction(cc.Sequence:create(spawn3, spawn4));

    end

    return 3.5;
end
